package com.ruoyix.flowable.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyix.common.utils.StringUtils;
import com.ruoyix.common.core.page.TableDataInfo;
import com.ruoyix.common.core.domain.PageQuery;
import com.ruoyix.flowable.domain.BpmTaskAssignee;
import com.ruoyix.flowable.mapper.BpmTaskAssigneeMapper;
import lombok.RequiredArgsConstructor;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.Model;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.springframework.stereotype.Service;
import com.ruoyix.flowable.domain.bo.BpmProcessDefinitionBo;
import com.ruoyix.flowable.domain.vo.BpmProcessDefinitionVo;
import com.ruoyix.flowable.service.IBpmProcessDefinitionService;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Collection;

/**
 * 流程定义Service业务层处理
 *
 * @author ruoyi
 * @date 2023-11-23
 */
@RequiredArgsConstructor
@Service
public class BpmProcessDefinitionServiceImpl implements IBpmProcessDefinitionService {


    private final RepositoryService repositoryService;

    private final BpmTaskAssigneeMapper bpmTaskAssigneeMapper;


    /**
     * 查询流程定义
     */
    @Override
    public BpmProcessDefinitionVo queryById(String id){
        return new BpmProcessDefinitionVo();
    }

    /**
     * 查询流程定义列表
     */
    @Override
    public TableDataInfo<BpmProcessDefinitionVo> queryPageList(BpmProcessDefinitionBo bo, PageQuery pageQuery) {
        List<BpmProcessDefinitionVo> result = new ArrayList<>();
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        if (StringUtils.isNotEmpty(bo.getProcessDefinitionKey())) {
            query.processDefinitionKeyLike("%" + bo.getProcessDefinitionKey() + "%");
        }
        if (StringUtils.isNotEmpty(bo.getProcessDefinitionName())) {
            query.processDefinitionNameLike("%" + bo.getProcessDefinitionName() + "%");
        }
        List<ProcessDefinition> processDefinitionList = query.latestVersion().listPage((pageQuery.getPageNum() - 1) * pageQuery.getPageSize(), pageQuery.getPageSize() * pageQuery.getPageNum());
        processDefinitionList.forEach(item->{
            BpmProcessDefinitionVo bpmProcessDefinitionVo = new BpmProcessDefinitionVo();
            bpmProcessDefinitionVo.setId(item.getId());
            bpmProcessDefinitionVo.setProcessDefinitionKey(item.getKey());
            bpmProcessDefinitionVo.setProcessDefinitionName(item.getName());
            bpmProcessDefinitionVo.setDescription(item.getDescription());
            bpmProcessDefinitionVo.setProcessDefinitionVersion(String.valueOf(item.getVersion()));
            bpmProcessDefinitionVo.setProcessDefinitionState(item.isSuspended()?1L:2L);
            bpmProcessDefinitionVo.setXmlName(item.getResourceName());
            Deployment deployment = repositoryService.createDeploymentQuery().deploymentId(item.getDeploymentId()).singleResult();

            Model model = repositoryService.createModelQuery().deploymentId(deployment.getId()).singleResult();
            bpmProcessDefinitionVo.setProcessDeploymentTime(deployment.getDeploymentTime());
            bpmProcessDefinitionVo.setProcessDeploymentId(deployment.getId());
            result.add(bpmProcessDefinitionVo);
        });

        return TableDataInfo.build(result);
    }

    public void getTaskAssigneeList(String processDefinitionId){
        List<UserTask> userTasks = new ArrayList<>();

        // 获取 BpmnModel
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);

        // 获取流程定义中的所有流程元素
        Collection<FlowElement> flowElements = bpmnModel.getProcesses().get(0).getFlowElements();

        // 遍历流程元素，筛选出所有的用户任务节点
        for (FlowElement element : flowElements) {
            if (element instanceof UserTask) {
                userTasks.add((UserTask) element);
            }
        }

        System.out.println(userTasks);
    }


    /**
     * 删除流程定义列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteWithValidByIds(String id){
       //根据当前流程定义ID查询该流程定义下是否有运行中的流程实例
        List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).list();
        if (!list.isEmpty()) {
            throw new RuntimeException("该流程定义下有正在运行的流程实例，不能删除！");
        }
        //根据流程定义ID删除流程定义
        repositoryService.deleteDeployment(id, true);
        //根据流程定义id删除bpm_task_assignee信息
        QueryWrapper<BpmTaskAssignee> wrapper = Wrappers.query();
        wrapper.eq("process_definition_id",id);
        bpmTaskAssigneeMapper.delete(wrapper);
        return true;

    }
}
